home *** CD-ROM | disk | FTP | other *** search
/ Java 1996 August / Java - Summer 1996.iso / kaffe-0.2 / kaffe / constants.c < prev    next >
C/C++ Source or Header  |  1996-02-12  |  5KB  |  237 lines

  1. /*
  2.  * constants.c
  3.  * Constant management.
  4.  *
  5.  * Copyright (c) 1996 Systems Architecture Research Centre,
  6.  *           City University, London, UK.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * Written by Tim Wilkinson <tim@sarc.city.ac.uk>, February 1996.
  12.  */
  13.  
  14. #define    RDBG(s)
  15.  
  16. #include <stdio.h>
  17. #include <assert.h>
  18. #include "gtypes.h"
  19. #include "constants.h"
  20. #include "object.h"
  21. #include "classMethod.h"
  22.  
  23. static strconst* strhash[STRHASHSZ];
  24. static strpair* strpairhash[STRHASHSZ];
  25.  
  26. /*
  27.  * Read in constant pool from opened file.
  28.  */
  29. constants*
  30. readConstantPool(classFile* fp)
  31. {
  32.     constants* info;
  33.     u4* pool;
  34.     u1* tags;
  35.     int i;
  36.     u1 type;
  37.     u2 len;
  38.     strconst* c;
  39.     char* uc;
  40.     u1 d1;
  41.     u2 d2, d2b;
  42.     u4 d4;
  43.  
  44.     info = (constants*)malloc(sizeof(constants));
  45.     if (info == 0) {
  46.         return (0);
  47.     }
  48.  
  49.     readu2(&info->size, fp);
  50. RDBG(    printf("constant_pool_count=%d\n", info->size);    )
  51.  
  52.     /* Allocate space for tags and data */
  53.     pool = (u4*)malloc((sizeof(u4) + sizeof(u1)) * info->size);
  54.     if (pool == 0) {
  55.         return (0);
  56.     }
  57.     tags = (u1*)&pool[info->size];
  58.     info->data = pool;
  59.     info->tags = tags;
  60.  
  61.     pool[0] = 0;
  62.     tags[0] = CONSTANT_Unknown;
  63.     for (i = 1; i < info->size; i++) {
  64.  
  65.         readu1(&type, fp);
  66. RDBG(        printf("Constant type %d\n", type);            )
  67.         tags[i] = type;
  68.  
  69.         if (type == CONSTANT_Utf8) {
  70.             readu2(&len, fp);
  71.             c = (strconst*)malloc(sizeof(strconst) + len + 1);
  72.             if (c == 0) {
  73.                 return (0);
  74.             }
  75.             readm(c->data, len, sizeof(u1), fp);
  76.             c->data[len] = 0;
  77. RDBG(            printf("Utf8=%s\n", c->data);            )
  78.  
  79.             pool[i] = (u4)addStringConstant(c);
  80.         }
  81.         else if (type == CONSTANT_Unicode) {
  82.             abort();
  83.             readu2(&len, fp);
  84.             uc = (u1*)malloc(len * 2 + 1);
  85.             readm(uc, len, sizeof(u2), fp);
  86.             uc[len * 2] = 0;
  87.             abort();
  88.         }
  89.         else switch (type) {
  90.         case CONSTANT_Class:
  91.             readu2(&d2, fp);
  92.             pool[i] = d2;
  93.             break;
  94.  
  95.         case CONSTANT_String:
  96.             readu2(&d2, fp);
  97.             pool[i] = d2;
  98.             tags[i] = CONSTANT_Chararray;
  99.             break;
  100.  
  101.         case CONSTANT_Fieldref:
  102.         case CONSTANT_Methodref:
  103.         case CONSTANT_InterfaceMethodref:
  104.         case CONSTANT_NameAndType:
  105.             readu2(&d2, fp);
  106.             readu2(&d2b, fp);
  107.             pool[i] = (d2b << 16) | d2;
  108.             break;
  109.  
  110.         case CONSTANT_Integer:
  111.         case CONSTANT_Float:
  112.             readu4(&d4, fp);
  113.             pool[i] = d4;
  114.             break;
  115.  
  116.         case CONSTANT_Long:
  117.         case CONSTANT_Double:
  118.             /* NON-PORTABLE!!! */
  119.             readu4(&d4, fp);
  120.             pool[i+1] = d4;
  121.             tags[i+1] = CONSTANT_Unknown;
  122.             readu4(&d4, fp);
  123.             pool[i] = d4;
  124.             i++;
  125.             break;
  126.  
  127.         default:
  128.             fprintf(stderr, "Bad constant %d\n", type);
  129.             return (0);
  130.         }
  131.     }
  132.  
  133.     /* Now create any string pairs required and any string objects */
  134.     for (i = 0; i < info->size; i++) {
  135.         if (tags[i] == CONSTANT_NameAndType) {
  136.             assert(tags[NAMEANDTYPE_NAME(i, info)] == CONSTANT_Utf8);
  137.             assert(tags[NAMEANDTYPE_SIGNATURE(i, info)] == CONSTANT_Utf8);
  138.             addStringConstantPair((char*)pool[NAMEANDTYPE_NAME(i, info)], (char*)pool[NAMEANDTYPE_SIGNATURE(i, info)]);
  139.         }
  140.     }
  141.  
  142.     return (info);
  143. }
  144.  
  145. /*
  146.  * Add a string to the string pool.
  147.  * If already there, free the new one and return the old one.
  148.  */
  149. char*
  150. addStringConstant(strconst* s)
  151. {
  152.     strconst* ptr;
  153.     uint32 hash;
  154.     int i;
  155.  
  156.     for (hash = 0,i = 0; s->data[i] != 0; i++) {
  157.         hash = hash * 33 + s->data[i];
  158.     }
  159.     hash %= STRHASHSZ;
  160.  
  161.     for (ptr = strhash[hash]; ptr != 0; ptr = ptr->next) {
  162.         if (strcmp(ptr->data, s->data) == 0) {
  163.             free(s);
  164.             return (ptr->data);
  165.         }
  166.     }
  167.     s->next = strhash[hash];
  168.     s->string = 0;
  169.     s->obj.mtable = 0;
  170.     s->obj.idx = 0;
  171.     s->obj.size = i;
  172.     s->obj.type = 0;
  173.     strhash[hash] = s;
  174.     return (s->data);
  175. }
  176.  
  177. /*
  178.  * Add string pair to the pool.
  179.  */
  180. strpair*
  181. addStringConstantPair(char* s1, char* s2)
  182. {
  183.     uint32 hash;
  184.     int i;
  185.     strpair* ptr;
  186.  
  187.     hash = 0;
  188.     for (i = 0; s1[i] != 0; i++) {
  189.         hash = hash * 33 + s1[i];
  190.     }
  191.     for (i = 0; s2[i] != 0; i++) {
  192.         hash = hash * 33 + s2[i];
  193.     }
  194.  
  195.     for (ptr = strpairhash[hash % STRHASHSZ]; ptr != 0; ptr = ptr->next) {
  196.         if (ptr->s1 == s1 && ptr->s2 == s2) {
  197.             return (ptr);
  198.         }
  199.     }
  200.     ptr = (strpair*)malloc(sizeof(strpair));
  201.     if (ptr == 0) {
  202.         return (0);
  203.     }
  204.     ptr->next = strpairhash[hash % STRHASHSZ];
  205.     ptr->hash = hash;
  206.     ptr->s1 = s1;
  207.     ptr->s2 = s2;
  208.     strpairhash[hash % STRHASHSZ] = ptr;
  209.     return (ptr);
  210. }
  211.  
  212. /*
  213.  * Lookup a string pair in the pool.
  214.  */
  215. strpair*
  216. lookupStringPair(char* s1, char* s2)
  217. {
  218.     uint32 hash;
  219.     int i;
  220.     strpair* ptr;
  221.  
  222.     hash = 0;
  223.     for (i = 0; s1[i] != 0; i++) {
  224.         hash = hash * 33 + s1[i];
  225.     }
  226.     for (i = 0; s2[i] != 0; i++) {
  227.         hash = hash * 33 + s2[i];
  228.     }
  229.  
  230.     for (ptr = strpairhash[hash % STRHASHSZ]; ptr != 0; ptr = ptr->next) {
  231.         if (ptr->s1 == s1 && ptr->s2 == s2) {
  232.             return (ptr);
  233.         }
  234.     }
  235.     return (0);
  236. }
  237.